package com.cjh.wechat.websocket.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.cjh.wechat.commom.pojo.Friend;
import com.cjh.wechat.commom.pojo.Notify;
import com.cjh.wechat.commom.pojo.NotifyGroup;
import com.cjh.wechat.commom.pojo.Team;
import com.cjh.wechat.commom.pojo.User;
import com.cjh.wechat.commom.type.ApplyStatus;
import com.cjh.wechat.commom.type.ReadStatus;
import com.cjh.wechat.commom.util.BasicUtil;
import com.cjh.wechat.commom.vo.MineVo;
import com.cjh.wechat.commom.vo.ShowFriendVo;
import com.cjh.wechat.websocket.dao.TeamDao;
import com.cjh.wechat.websocket.dao.UserDao;
import com.cjh.wechat.websocket.service.FriendService;
import com.cjh.wechat.websocket.service.NotifyGroupService;
import com.cjh.wechat.websocket.service.NotifyService;
import com.cjh.wechat.websocket.service.RedisService;
import com.cjh.wechat.websocket.service.UserAndGroupService;
import redis.clients.jedis.Jedis;

@Service
public class RedisFriendServiceImpl implements FriendService
{
    @Resource
    private RedisService        redisService;
    @Resource
    private UserAndGroupService userAndGroupService;
    @Resource
    private TeamDao             teamDao;
    @Resource
    private UserDao             userDao;
    @Resource
    private NotifyService       notifyService;
    @Resource
    private NotifyGroupService  notifyGroupService;
    
    @Override
    public void inviteFriend(String uid, String gid)
    {
        NotifyGroup notifyGroup = new NotifyGroup();
        notifyGroup.setDateTime(BasicUtil.getDateTime());
        notifyGroup.setIsRead(ReadStatus.UNREAD.value);
        notifyGroup.setContent("群主|管理员邀请" + uid + "加入该群");
        notifyGroup.setType(ApplyStatus.SYS.value);
        notifyGroup.setGid(gid);
        notifyGroup.setFromUid(uid);
        notifyGroupService.insertSelective(notifyGroup);
        if (notifyService.isExist(uid, gid, ApplyStatus.INIT.value))
        {
            // 重复
        }
        else
        {
            Notify notify = new Notify();
            notify.setUid(uid);
            notify.setFromUid(gid);
            notify.setDateTime(BasicUtil.getDateTime());
            notify.setIsRead(ReadStatus.UNREAD.value);
            notify.setContent("群组" + gid + "邀请您加入该群组");
            notify.setType(ApplyStatus.INIT.value);
            notify.setHref("group");
            notifyService.insertSelective(notify);
        }
    }
    
    @Override
    public List<User> inviteFriendList(String uid, String gid)
    {
        List<User> inviteList = new ArrayList<User>();
        try (Jedis jedis = redisService.get())
        {
            Set<String> set = jedis.zrange(uid, 0, -1);
            Iterator<String> iter = set.iterator();
            List<String> uids = new ArrayList<String>();
            while (iter.hasNext())
            {
                String fid = iter.next();
                uids.add(fid);
            }
            List<User> users = userAndGroupService.findByGroupId(gid);
            for (User user : users)
            {
                uids.remove(user.getId());
            }
            for (String id : uids)
            {
                User user = userDao.findById(id);
                inviteList.add(user);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return inviteList;
    }
    
    @Override
    public void insert(Friend friend)
    {
        try (Jedis jedis = redisService.get())
        {
            jedis.zadd(friend.getUid(), friend.getTno(), friend.getFid());
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public void delFriend(String id, String friendId)
    {
        try (Jedis jedis = redisService.get())
        {
            jedis.zrem(id, friendId);
            jedis.zrem(friendId, id);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public void updateByPrimaryKeySelective(String id, String friendId, Integer tno)
    {
        try (Jedis jedis = redisService.get())
        {
            jedis.zadd(id, tno, friendId);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public List<Friend> findByUid(String uid)
    {
        List<Friend> friends = new ArrayList<Friend>();
        try (Jedis jedis = redisService.get())
        {
            Set<String> set = jedis.zrange(uid, 0, -1);
            Iterator<String> iter = set.iterator();
            while (iter.hasNext())
            {
                String fid = iter.next();
                long tno = jedis.zrevrank(uid, fid);
                Friend friend = new Friend();
                friend.setUid(uid);
                friend.setFid(fid);
                friend.setTno((int) tno);
                friends.add(friend);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return friends;
    }
    
    @Override
    public List<ShowFriendVo> showFriend(String id)
    {
        List<ShowFriendVo> showFriendVos = new ArrayList<ShowFriendVo>();
        List<Team> teams = teamDao.findByUid(id);
        for (Team team : teams)
        {
            try (Jedis jedis = redisService.get())
            {
                Set<String> set = jedis.zrangeByScore(id, team.getNo(), team.getNo());
                Iterator<String> iter = set.iterator();
                ShowFriendVo vo = new ShowFriendVo();
                vo.setTeam(team);
                List<User> users = new ArrayList<>();
                while (iter.hasNext())
                {
                    String fid = iter.next();
                    User user = userDao.findById(fid);
                    users.add(user);
                }
                vo.setUsers(users);
                showFriendVos.add(vo);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
        return showFriendVos;
    }
    
    @Override
    public void addFriend(String id, String friendId, Integer tno)
    {
        try (Jedis jedis = redisService.get())
        {
            jedis.zadd(id, tno, friendId);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
    
    @Override
    public List<MineVo> getByTno(String uid, int tno)
    {
        List<MineVo> list = new ArrayList<MineVo>();
        try (Jedis jedis = redisService.get())
        {
            Set<String> set = jedis.zrangeByScore(uid, tno, tno);
            Iterator<String> iter = set.iterator();
            while (iter.hasNext())
            {
                String fid = iter.next();
                User user = userDao.findById(fid);
                MineVo vo = new MineVo();
                vo.setAvatar(user.getAvatar());
                vo.setId(user.getId());
                vo.setSign(user.getSign());
                vo.setStatus(user.getStatus());
                vo.setUsername(user.getUsername());
                list.add(vo);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return list;
    }
    
    @Override
    public List<Friend> findByTno(String uid, int tno)
    {
        List<Friend> friends = new ArrayList<Friend>();
        try (Jedis jedis = redisService.get())
        {
            Set<String> set = jedis.zrangeByScore(uid, tno, tno);
            Iterator<String> iter = set.iterator();
            while (iter.hasNext())
            {
                String fid = iter.next();
                Friend friend = new Friend();
                friend.setUid(uid);
                friend.setFid(fid);
                friend.setTno((int) tno);
                friends.add(friend);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return friends;
    }
    
    @Override
    public Friend findByUidAndFid(String id, String friendId)
    {
        Friend friend = new Friend();
        try (Jedis jedis = redisService.get())
        {
            double tno = jedis.zscore(id, friendId);
            friend.setUid(id);
            friend.setFid(friendId);
            friend.setTno((int) tno);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return friend;
    }
}
